package geom;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Vector;

/**
 * Cette classe represente un Polygone en 2 dimensions.
 * @author Romain POGU
 * @author Anthony MAUGENDRE
 * @version 1.0
 *
 */
public class Polygone extends FigureGraphique {
	/**
	 * 
	 */
	private static final long serialVersionUID = -5093940412909387873L;
	public Vector<Point_2D> points;
	private int nbPoints;

	/**
	 * @param nom nom du polygone
	 * @param cc couleur de contour
	 * @param cr couleur de remplissage
	 * @param points Vector des points des sommets du polygones
	 */

	public Polygone(String nom, Color cc, Color cr, Vector<Point_2D> points) {
		super(nom, cc, cr);
		this.points = new Vector<Point_2D>(points);
		nbPoints = points.size();
		// TODO Auto-generated constructor stub
	}
	public Polygone() {
		super("", Color.BLUE, Color.BLUE);
		this.points = new Vector<Point_2D>();
		nbPoints = 0;
		// TODO Auto-generated constructor stub
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see FigureGraphique#dessineToi(java.awt.Graphics)
	 */
	@Override
	/**
	 * Methode qui dessine le polygone 
	 * 
	 * @param g contexte graphique
	 * 
	 */
	public void dessineToi(Graphics g) {
		int xs[] = new int[nbPoints];
		int ys[] = new int[nbPoints];
		g.setColor(cc);
		for (int i = 0; i < nbPoints; i++) {
			xs[i] = (int) points.get(i).getX();
			ys[i] = (int) points.get(i).getY();
			//elastique adding
			g.fillOval(xs[i], ys[i], 10, 10);
		}
		/*g.setColor(cr);
		// dessiner le remplissage du cercle
		g.fillPolygon(xs, ys, nbPoints);
		g.setColor(cc);
		// dessiner le contour du cercle
		g.drawPolygon(xs, ys, nbPoints);
		g.drawString(nom, getCentre().x, getCentre().y);*/
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see Figure#contient(Point_2D)
	 */
	@Override
	
	/**
	 * 
	 * Methode qui teste si un point appartient a un polygone. 
	 * Cette methode marche aussi bien pour un polygone concave que convexe.
	 * 
	 * La methode utilise les coordonnees du point que l'on souhaite tester. 
	 * A partir de ce point, l'algorithme recupere les coordonnees des intersections 
	 * entre les cotes du poygone et une droite parallele a l axe des abscisses qui passe par le point teste.
	 * Si la parite du nombre d intersection avant le point (x<abscisse du point teste) 
	 * est la meme que la parite du nombre d'intersection apres le point qlors le point appartient au polygone.
	 * Si les parites du nombre de point avant et apres le point sont differentes, 
	 * alors le point n'appartient pas au polygone.
	 * 
	 * @param p Point_2D
	 * @return boolean 1 si le polygone contient p, 0 sinon
	 * 
	 */
	public boolean contient(Point_2D p) {
		// TODO Auto-generated method stub
		// System.out.println("TEST CONTIENT");
		int j = nbPoints - 1;

		//Coordonnees en abscisse des cotes du polygone
		float polyX[] = new float[nbPoints];
		//Coordonnees en ordonnee des cotes du polygone
		float polyY[] = new float[nbPoints];
		
		//On recupere les coordonnees des cotes
		for (int z = 0; z < nbPoints; z++) {
			polyX[z] = (float) points.get(z).getX();
			polyY[z] = (float) points.get(z).getY();
		}
		float y = (float) p.getY();
		float x = (float) p.getX();
		
		//On initialise la parite a faux
		boolean parite = false;

		for (int i = 0; i < nbPoints; i++) {
			
			if (polyY[i] < y && polyY[j] >= y || polyY[j] < y && polyY[i] >= y) {
				
				if (polyX[i] + (y - polyY[i]) / (polyY[j] - polyY[i]) * (polyX[j] - polyX[i]) < x) {
					
					parite = !parite;
				
				}
			
			}
			j = i;
		}

		return parite;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see Figure#deplace(int, int)
	 */
	@Override
	
	/**
	 * 
	 * Methode qui permet de deplacer un polygone de dx en abscisse et de dy en ordonnee
	 * 
	 * @param dx distance en abscisse
	 * @param dy distance en ordonnee
	 * 
	 */
	public void deplace(int dx, int dy) {
		// TODO Auto-generated method stub
		for (Point_2D p : points)
			p.deplace(dx, dy);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see Figure#getCentre()
	 */
	@Override
	/**
	 * 
	 * Methode qui permet de recuperer les coordonnees du centre du polygone
	 * 
	 * @return Point_2d centre du polygone
	 * 
	 */
	public Point_2D getCentre() {
		// TODO Auto-generated method stub
		float aire = 0;
		float gX = 0, gY = 0;
		for (int i = 0; i < nbPoints; i++) {
			float aI = (float) (points.get(i).getX()
					* points.get((i + 1) % nbPoints).getY() - points.get(i)
					.getY()
					* points.get((i + 1) % nbPoints).getX());
			aire += aI;
			gX += aI
					* (points.get(i).getX() + points.get((i + 1) % nbPoints)
							.getX());
			gY += aI
					* (points.get(i).getY() + points.get((i + 1) % nbPoints)
							.getY());
		}
		aire /= 2.0;
		gX /= (6 * aire);
		gY /= (6 * aire);
		return new Point_2D((int) gX, (int) gY);
	}
	
	public void addPoint(Point_2D p){
		points.add(p);
		nbPoints=points.size();
	}
	public int getNbPoints() {
		return nbPoints;
	}
}
